package com.mc.moring.base

import android.annotation.SuppressLint
import android.content.Context
import android.content.res.AssetManager
import android.graphics.Bitmap
import android.telephony.TelephonyManager
import android.text.TextUtils
import androidx.lifecycle.ViewModel
import com.google.gson.GsonBuilder
import com.google.gson.ToNumberPolicy
import com.mc.moring.app.LogUtils
import com.mc.moring.bean.ZiLiPageUserDataBean
import com.mc.moring.util.SPUtils
import com.mc.moring.util.SharePreUtil
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.ResponseBody
import org.json.JSONException
import org.json.JSONObject
import retrofit2.Response
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.nio.charset.StandardCharsets
import java.util.*
import kotlin.collections.HashMap


interface HttpCallback{
     fun onSuccess(data:String)
     fun onFaill(e:String)
 }

interface HttpBitmapCallback{
    fun onSuccess(data:Bitmap)
    fun onFaill(e:String)
}
open class BaseModle : ViewModel() {

    val replaceSymbol = "ZiLiPage"
    val ZiLiPage_App_ID = "com.mc.moring"
//    val ZiLiPage_App_ID = CoreConfig.App_id



    fun getZiLiPageJson(valueMap: Map<String, Any>?, addHeader: Boolean): String {
        val params: MutableMap<String, Any?> = HashMap()
        try {
            params["body"] = valueMap
            if (!addHeader) {
                params["headers"] = getZiLiPageHead()
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
//        var requestValue = Gson().toJson(params)
        var requestValue = GsonBuilder()
            .setObjectToNumberStrategy(ToNumberPolicy.LAZILY_PARSED_NUMBER)
            .create()
            .toJson(params)
        if (addHeader) {
//            requestValue = Gson().toJson(valueMap)
            requestValue = GsonBuilder()
                .setObjectToNumberStrategy(ToNumberPolicy.LAZILY_PARSED_NUMBER)
                .create()
                .toJson(params)
        }
        var fParams = RSAUtil.encryptDataByPublicKey(
            requestValue.toString().toByteArray(StandardCharsets.UTF_8),
            RSAUtil.keyStrToZiLiPagePublicKey(RSAUtil.publicKeyString)
        )
        if (addHeader) {
            fParams = requestValue
        }
        return fParams
    }

    fun getZiLiPageJsonNew(valueMap: Map<String, Any>?, addHeader: Boolean): String {
        val params: MutableMap<String?, Map<String, Any>?> = HashMap()
        try {
            params["body"] = valueMap
            if (!addHeader) {
                params["headers"] = getZiLiPageHead()
            }
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
        var requestValue = GsonBuilder()
            .setObjectToNumberStrategy(ToNumberPolicy.LAZILY_PARSED_NUMBER)
            .create().toJson(params)
        if (addHeader) {
            requestValue =GsonBuilder()
                .setObjectToNumberStrategy(ToNumberPolicy.LAZILY_PARSED_NUMBER)
                .create().toJson(valueMap)
        }

        var fParams = RSAUtil.encryptDataByPublicKey(
            requestValue.toString().toByteArray(StandardCharsets.UTF_8),
            RSAUtil.keyStrToZiLiPagePublicKey(RSAUtil.publicKeyString)
        )
        if (addHeader) {
            fParams = requestValue
        }
        return fParams
    }

    fun Any.toJsonRequestBody(format: String = "application/json"): RequestBody {
        return GsonBuilder()
            .setObjectToNumberStrategy(ToNumberPolicy.LAZILY_PARSED_NUMBER)
            .create()
            .toJson(this).toRequestBody(format.toMediaType())
    }

    fun Any.toStringRequestBody(format: String = "application/json"): RequestBody {
        return format.toRequestBody(format.toMediaType())
    }

    public fun getZiLiPageHead(): Map<String, Any> {
        val app_id = BaseApplication.getInstance().packageName
        val android_id = SPUtils.getAndroidId()
        val headMap = HashMap<String, Any>()
        headMap["App_id"] = "com.mc.moring"
        headMap["App_name"] = "MONICASH"
        headMap["App_version"] = "1.0.0"
        headMap["accept-language"] = "es"
        ZiLiPageUserDataBean.getInstance().token?.let { token ->
            if (!token.isNullOrEmpty()) {
                LogUtils.logE("token:$token")
                headMap["Authorization"] = "Bearer "+token
                headMap["distinctId"] = ZiLiPageUserDataBean.getInstance().customerId
            } else {
                headMap["distinctId"] = android_id + ""
            }
        }
//        headMap["Authorization"] = "Bearer "+ZiLiPageUserDataBean.getInstance().token
        SharePreUtil.saveStringData("Token",ZiLiPageUserDataBean.getInstance().token)
        LogUtils.logE( "Token "+ZiLiPageUserDataBean.getInstance().token)
        return headMap
    }

    fun decryptingZiLiPageData(response: Response<ResponseBody>): String {
        try {
            val value = response.body()?.string()
            val valueResult = RSAUtil.getDecryptApiZiLiPageData(value ?: "")
            return valueResult ?: ""
        }catch (e:Exception){
            e.printStackTrace()
        }
        return ""
    }

    @SuppressLint("HardwareIds")
    open fun getZiLiPageDeviceId(context: Context): String? {
        val telephonyManager =
            context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        return try {
            telephonyManager.deviceId.toString()
        } catch (e: java.lang.Exception) {
            getZiLiPageDeviceID(context)
        }
    }

    open fun getZiLiPageDeviceID(context: Context?): String? {
        var deviceID: String? = context?.let { SaveZiLiPageTool(it).getKeyValue("UUID") }
        if (TextUtils.isEmpty(deviceID)) {
            deviceID = UUID.randomUUID().toString()
            context?.let { SaveZiLiPageTool(it).puttKeyValue("UUID", deviceID) }
        }
        return deviceID
    }

    open fun isSuccess(jsonObject: JSONObject): Boolean {
        try {
            val code = jsonObject.getString("code")
            if (TextUtils.equals(code, "0000") || TextUtils.equals(code, "000")) {
                return true
            }
        } catch (e: JSONException) {
            e.printStackTrace()
        }
        return false
    }

    open fun getBooleanToJson(jsonObject: JSONObject?, key: String?): Boolean {
        if (jsonObject != null) {
            try {
                return jsonObject.getBoolean(key)
            } catch (e: JSONException) {
                e.printStackTrace()
            }
        }
        return false
    }

    open fun getStringToJson(jsonObject: JSONObject?, key: String?): String? {
        if (jsonObject != null) {
            try {
                return jsonObject.getString(key)
            } catch (e: JSONException) {
                e.printStackTrace()
            }
        }
        return null
    }

    fun getAssetsValue(context: Context): String {
        var result = ""
        val assetManager: AssetManager = context.assets
        try {
            val inputStream = assetManager.open("lucra_area.json")
            val reader = BufferedReader(InputStreamReader(inputStream))
            val stringBuilder = StringBuilder()
            var line: String?
            while (reader.readLine().also { line = it } != null) {
                stringBuilder.append(line)
            }
            result = stringBuilder.toString()
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return result
    }

}